package com.dushuren.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dushuren.project.common.ErrorCode;
import com.dushuren.project.exception.BusinessException;
import com.dushuren.project.mapper.TagMapper;
import com.dushuren.project.mapper.TeamMapper;
import com.dushuren.project.mapper.UserMapper;
import com.dushuren.project.mapper.UserTeamMapper;
import com.dushuren.project.model.dto.TeamAddRequest;
import com.dushuren.project.model.dto.TeamListQueryRequest;
import com.dushuren.project.model.dto.TeamUpdateBaseRequest;
import com.dushuren.project.model.dto.TeamUpdateCureRequest;
import com.dushuren.project.model.entity.Team;
import com.dushuren.project.model.entity.User;
import com.dushuren.project.model.entity.UserTeam;
import com.dushuren.project.model.vo.TeamVo;
import com.dushuren.project.model.vo.UserVo;
import com.dushuren.project.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.dushuren.project.constant.TeamConstant.*;
import static com.dushuren.project.constant.TeamCureExamineConstant.*;
import static com.dushuren.project.constant.UserConstant.USER_CREDITS_NUM;

/**
* @author qieqie
* @description 针对表【team(队伍管理)】的数据库操作Service实现
* @createDate 2022-10-17 08:34:21
*/
@Service
public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
    implements TeamService {

  @Resource
  TeamMapper teamMapper;

  @Resource
  TagMapper tagMapper;

  @Resource
  TagService tagService;

  @Resource
  UserTeamService userTeamService;

  @Resource
  UserTeamMapper userTeamMapper;

  @Resource
  TeamCureExamineService teamCureExamineService;

  @Resource
  UserService userService;

  @Resource
  UserMapper userMapper;

  /**
   * 添加队伍
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Boolean addTeam(TeamAddRequest teamAddRequest, HttpServletRequest request) {
	UserVo userVO = userService.getIsServletRequest(request);
	// 校验 用户信息
	if (StringUtils.isAnyBlank(teamAddRequest.getTeamType(),
	  	teamAddRequest.getTeamName(),teamAddRequest.getTeamTechnologyType(),teamAddRequest.getTeamName())) {
	  throw new BusinessException(ErrorCode.NULL_ERROR);
	}
	if (teamAddRequest.getUserId() == null) {
	  throw new BusinessException(ErrorCode.NULL_ERROR);
	}
	if (userVO.getCreditsNum() < USER_CREDITS_NUM) {
	  throw new BusinessException(ErrorCode.NO_AUTH);
	}
	if (!teamAddRequest.getUserId().equals(userVO.getId())) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	if (teamAddRequest.getTeamDescription().length() > 300) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	// 队伍名称
	if (teamAddRequest.getTeamName().length() > TEAM_NAME) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	// 队伍人数
	if (TEAM_MAX_NUM < teamAddRequest.getMaxNum() || TEAM_MIN_NUM > teamAddRequest.getMaxNum()) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}

	// 校验 队伍类型（APP 、 网页、 小程序） 队伍技术类型（SpringBoot、java、HTML等）
	tagService.checkTeamTags(teamAddRequest.getTeamType(),teamAddRequest.getTeamTechnologyType());

	// 查询 team 表，队伍的count < 5
	// todo 查询 加入队伍列表
	// todo 查询 创建队伍 和 加入队伍的 人数 <= 5
	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	queryWrapperTeam.select("id");
	queryWrapperTeam.eq("userId",teamAddRequest.getUserId());
	queryWrapperTeam.notIn("teamApplyState", TEAM_STATE_REFUSE);
 	Long countTeam = teamMapper.selectCount(queryWrapperTeam);
	if (countTeam >= TEAM_CREATE_COUNT) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "申请队伍列表以达到5，不能继续申请创建");
	}
	Team team = new Team();
	team.setId(null);
	team.setUserId(userVO.getId());

	BeanUtils.copyProperties(teamAddRequest, team);
	// 存入 team
	boolean save = this.save(team);
	// 存入 user_team
	UserTeam userTeam = new UserTeam();
	userTeam.setUserId(userVO.getId());
	userTeam.setTeamId(team.getId());
	userTeam.setJoinTeam(new Date());
	boolean save1 = userTeamService.save(userTeam);
	if (!save1) {
	  throw new BusinessException(ErrorCode.SYSTEM_ERROR);
	}
	return save;
  }

  /**
   * 删除队伍
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Boolean deleteTeam(Long teamId, HttpServletRequest request) {
	UserVo userVO = userService.getIsServletRequest(request);
	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	if (userVO.getId() == null || userVO.getId() < 0) {
	  throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
	}
	// 校验身份
	queryWrapperTeam.select("id");
	queryWrapperTeam.eq("userId",userVO.getId());
	queryWrapperTeam.eq("id",teamId);
	Long teamCount = teamMapper.selectCount(queryWrapperTeam);
	if (teamCount != 1) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR,"队伍不存在");
	}
	QueryWrapper<UserTeam> queryWrapperUserTeam = new QueryWrapper<>();
	queryWrapperUserTeam.select("id");
	queryWrapperUserTeam.eq("teamId",teamId);
	Long userTeamCount = userTeamMapper.selectCount(queryWrapperUserTeam);
	if (userTeamCount != 1 ) {
	  throw new BusinessException(ErrorCode.DELETE_ERROR, "队伍中存在其余人员");
	}
	// 删除队伍
	boolean removeTeam = this.removeById(teamId);
	boolean userTeamRemove = userTeamService.remove(queryWrapperUserTeam);
	if (!removeTeam && !userTeamRemove) {
	  throw new BusinessException(ErrorCode.SYSTEM_ERROR);
	}
	return true;
  }



  /***
   * 更新公开的队伍信息
   */
  @Override
  public Boolean updateBaseTeam(TeamUpdateBaseRequest teamUpdateBaseRequest, HttpServletRequest request) {
	UserVo userVO = userService.getIsServletRequest(request);
	Long userId = teamUpdateBaseRequest.getUserId();
	if (!userId.equals(userVO.getId())) {
	  throw new BusinessException(ErrorCode.NO_AUTH);
	}
	Long teamId = teamUpdateBaseRequest.getId();
	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	queryWrapperTeam.select("id", "maxNum", "teamType", "teamTechnologyType");
	queryWrapperTeam.eq("id",teamId);
	queryWrapperTeam.eq("userId", userId);
	List<Team> teamList = teamMapper.selectList(queryWrapperTeam);
	if (teamList.size() != 1) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	Integer maxNum = teamUpdateBaseRequest.getMaxNum();
	String teamType = teamUpdateBaseRequest.getTeamType();
	String teamTechnologyType = teamUpdateBaseRequest.getTeamTechnologyType();
	// 校验 tags
	tagService.checkTeamTags(teamType,teamTechnologyType);
	// 不更新重复数据
	Team team = teamList.get(0);
	UpdateWrapper<Team> updateWrapperTeam = new UpdateWrapper<>();
	updateWrapperTeam.eq("id", teamId);
	updateWrapperTeam.eq("userId", userId);
	if (!team.getMaxNum().equals(maxNum)) {
	  updateWrapperTeam.set("maxNum",maxNum);
	}
	if (!team.getTeamType().equals(teamType)) {
	  updateWrapperTeam.set("teamType",teamType);
	}
	if (!team.getTeamTechnologyType().equals(teamTechnologyType)) {
	  updateWrapperTeam.set("teamTechnologyType",teamTechnologyType);
	}
	try {
	  teamMapper.update(null, updateWrapperTeam);
	} catch (Exception e) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR,"修改的参数相同");
	}

	return true;
  }

  /**
   * 更新公开的队伍信息
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Long updateCureTeam(TeamUpdateCureRequest updateCureRequest, HttpServletRequest request) {
	// 校验登录态 | 队伍
	UserVo userVO = userService.getIsServletRequest(request);
	Long userId = updateCureRequest.getUserId();
	Long teamId = updateCureRequest.getTeamId();
	if (!userVO.getId().equals(userId)) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}

	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	queryWrapperTeam.select("teamName", "teamDescription", "teamAvatarUrl");
	queryWrapperTeam.eq("userId",userId);
	queryWrapperTeam.eq("id",teamId);
	List<Team> teams = teamMapper.selectList(queryWrapperTeam);
	if (teams.size() != 1) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	/*
	  逻辑 修改队伍公共信息时，
	  	如果修改的 teamName 这里就是判断 这个是否和上一次的相同
	  	下面的 teamDescription 也是一样的
	 */
	// 更新 队伍名称
	String teamName = updateCureRequest.getTeamName();
	// 更新 队伍介绍
	String teamDescription = updateCureRequest.getTeamDescription();
	// 更新队伍图片
	String teamAvatarUrl = updateCureRequest.getTeamAvatarUrl();

	// 校验 队伍信息
	// 更新 是否为 TeamName 队伍名称
	Long teamNameALong = 1L;
	Long teamDescriptionALong = 1L;
	Long teamAvatarUrlLong = 1L;
	if (StringUtils.isNotBlank(teamName) && !teamName.equals(teams.get(0).getTeamName())) {
	  // 校验 是否存在为审批的 申请
	  teamNameALong = teamCureExamineService.addApply(userId, teamId, TEAM_CURE_EXAMINE_NAME, teamName);
	}
	// 更新 是否为 teamDescription 队伍简介
	if (StringUtils.isNotBlank(teamDescription) && !teamDescription.equals(teams.get(0).getTeamDescription())) {
	  teamDescriptionALong = teamCureExamineService.addApply(userId, teamId, TEAM_CURE_EXAMINE_DESCRIPTION, teamDescription);
	}
	// 更新 是否为 teamAvatarUrl
	if (StringUtils.isNotBlank(teamAvatarUrl) && !teamAvatarUrl.equals(teams.get(0).getTeamAvatarUrl())) {
	  teamAvatarUrlLong = teamCureExamineService.addApply(userId, teamId, TEAM_CURE_EXAMINE_AvatarUrl, teamAvatarUrl);
	}
	if (teamNameALong == 1 && teamDescriptionALong == 1 && teamAvatarUrlLong == 1) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "更新内容相同，更新失败");
	}
	return 0L;
  }

  /**
   * 查询指定条件
   */
  @Override
  public List<TeamVo> listQueryTeam(TeamListQueryRequest teamListQueryRequest,Integer teamState) {
	Long teamId = teamListQueryRequest.getId();
	String teamName = teamListQueryRequest.getTeamName();
	String teamDescription = teamListQueryRequest.getTeamDescription();
	Integer maxNum = teamListQueryRequest.getMaxNum();
	String teamType = teamListQueryRequest.getTeamType();
	String teamTechnologyType = teamListQueryRequest.getTeamTechnologyType();
	Long userId = teamListQueryRequest.getUserId();

	  QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	queryWrapperTeam.select("id", "teamName", "teamDescription",
	  "maxNum", "teamType", "teamTechnologyType", "userId","createTime");
	queryWrapperTeam.eq("teamApplyState" ,teamState);
	if (teamId != null && teamId > 0) {
	  queryWrapperTeam.eq("id", teamId);
	}
	if (teamName != null && teamName.length() <= TEAM_NAME) {
	  queryWrapperTeam.like("teamName", teamName);
	}
	if (teamDescription != null && teamDescription.length() <= TEAM_DESCRIPTION_MAX) {
	  queryWrapperTeam.like("teamDescription", teamDescription);
	}
	if (maxNum != null && (TEAM_MIN_NUM <= maxNum && maxNum <= TEAM_MAX_NUM)) {
	  queryWrapperTeam.eq("maxNum", maxNum);
	}
	if (userId != null && userId > 0) {
	  queryWrapperTeam.eq("userId", userId);
	}
	if (teamType != null) {
	  queryWrapperTeam.eq("teamType", teamType);
	}
	if (teamTechnologyType != null) {
	  queryWrapperTeam.like("teamTechnologyType", teamTechnologyType);
	}
	return teamMapper.selectList(queryWrapperTeam).stream().map(
	  team -> {
		TeamVo teamVo = new TeamVo();
		BeanUtils.copyProperties(team, teamVo);
		return teamVo;
	  }
	).collect(Collectors.toList());
  }

  /**
   * 分页查询指定条件
   */
  @Override
  public Page<TeamVo> listPageQueryTeam(TeamListQueryRequest teamListQueryRequest, Integer teamState) {
	Long teamId = teamListQueryRequest.getId();
	String teamName = teamListQueryRequest.getTeamName();
	String teamDescription = teamListQueryRequest.getTeamDescription();
	Integer maxNum = teamListQueryRequest.getMaxNum();
	String teamType = teamListQueryRequest.getTeamType();
	String teamTechnologyType = teamListQueryRequest.getTeamTechnologyType();
	Long userId = teamListQueryRequest.getUserId();
	long current = teamListQueryRequest.getCurrent();
	long size  = teamListQueryRequest.getPageSize();

	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	queryWrapperTeam.select("id", "teamName", "teamDescription",
	  "maxNum", "teamType", "teamTechnologyType", "teamAvatarUrl", "userId","createTime");
	queryWrapperTeam.eq("teamApplyState" ,teamState);
	if (teamId != null && teamId > 0) {
	  queryWrapperTeam.eq("id", teamId);
	}
	if (teamName != null && teamName.length() <= TEAM_NAME) {
	  queryWrapperTeam.like("teamName", teamName);
	}
	if (teamDescription != null && teamDescription.length() <= TEAM_DESCRIPTION_MAX) {
	  queryWrapperTeam.like("teamDescription", teamDescription);
	}
	if (maxNum != null && (TEAM_MIN_NUM <= maxNum && maxNum <= TEAM_MAX_NUM)) {
	  queryWrapperTeam.eq("maxNum", maxNum);
	}
	if (userId != null && userId > 0) {
	  queryWrapperTeam.eq("userId", userId);
	}
	if (teamType != null) {
	  queryWrapperTeam.eq("teamType", teamType);
	}
	if (teamTechnologyType != null) {
	  queryWrapperTeam.like("teamTechnologyType", teamTechnologyType);
	}
	Page<Team> teamPage = this.page(new Page<>(current, size), queryWrapperTeam);
	Map<Long, List<TeamVo>> teamIdListMap = teamPage.getRecords().stream().map(team -> {
	  TeamVo teamVo = new TeamVo();
	  BeanUtils.copyProperties(team, teamVo);
	  teamVo.setMinNum(team.getMaxNum() - this.teamWantingAmount(team.getId()));
	  teamVo.setApply(3);
	  return teamVo;
	}).collect(Collectors.groupingBy(TeamVo::getId));
	Page<TeamVo> teamVoPage = new Page<>(teamPage.getCurrent(), teamPage.getSize(), teamPage.getTotal());
	teamVoPage.setRecords(teamIdListMap.values().stream()
	  .flatMap(Collection::stream)
	  .collect(Collectors.toList()));

	return teamVoPage;
  }



  /***
   * 校验team表中这个Id是否存在，teamApplyState 是否为 0 》 是否为审核状态
   */
  @Override
  public Boolean checkApplyState(Long teamId) {
	if (teamId == null) {
	  throw new BusinessException(ErrorCode.NULL_ERROR);
	}
	QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
	queryWrapper.select("id");
	queryWrapper.eq("id", teamId);
	queryWrapper.eq("teamApplyState", 0);
	Long count = teamMapper.selectCount(queryWrapper);
	if (count != 1) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	return true;
  }

  /**
   * 判断当前队伍加入人数 还差多为
   * @param teamId
   * @return
   */
  @Override
  public Long teamWantingAmount(Long teamId) {
	if (teamId <= 0) {
	throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	QueryWrapper<Team> queryWrapperTeam = new QueryWrapper<>();
	QueryWrapper<UserTeam> queryWrapperUserTeam = new QueryWrapper<>();
	queryWrapperTeam.select("maxNum");
	queryWrapperTeam.eq("id", teamId);
	// 获取到当前队伍能加入的人数
	Integer maxNum = teamMapper.selectOne(queryWrapperTeam).getMaxNum();
	if (maxNum == null) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "队伍不存在");
	}
	queryWrapperUserTeam.select("id");
	queryWrapperUserTeam.eq("teamId",teamId);
	// 获取到现在已加入队伍的人数
	Long count = userTeamMapper.selectCount(queryWrapperUserTeam);
	return maxNum - count;
  }

  /***
   * 获取当前队伍的成员信息
   */
  @Override
  public List<UserVo> allMember(Long teamId) {
	if (teamId == null || teamId <= 0) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
	queryWrapper.select("userId");
	queryWrapper.eq("teamId", teamId);
	List<Long> allUserId = userTeamMapper.selectList(queryWrapper).stream().map(UserTeam::getUserId).collect(Collectors.toList());
	QueryWrapper<User> queryWrapperUser = new QueryWrapper<>();
	queryWrapperUser.select("id","userStatus", "creditsNum","userAccount", "userName", "avatarUrl", "gender", "userProfile", "phone", "email", "tags");
	queryWrapperUser.in("id", allUserId);
	return userMapper.selectList(queryWrapperUser).stream().map(user -> {
	  UserVo userVo = new UserVo();
	  BeanUtils.copyProperties(user, userVo);
	  return userVo;
	}).collect(Collectors.toList());
  }

}




